#include <map>
#include <sstream>
#include "AdminChannel.h"
#include "AdminConfiguration.h"

AgoraAdmin::Channel::Channel(const unsigned int id, IChannel* parent, const unsigned int idParent, const std::string &name, const unsigned int maxNameLenght, const std::string &password, const unsigned int maxPasswordLenght, const std::string &motd, const unsigned int maxMotdLenght, const std::string &description, const unsigned int maxDescriptionLenght, const bool visible, const unsigned int maxUser, const unsigned int maxTalker)
: _id(id), _parent(parent), _idParent(idParent), _name(name), _maxNameLenght(maxNameLenght), _password(password), _maxPasswordLenght(maxPasswordLenght), _motd(motd), _maxMotdLenght(maxMotdLenght), _description(description), _maxDescriptionLenght(maxDescriptionLenght), _visible(visible), _maxUser(maxUser), _maxTalker(maxTalker)
{
	IDatabase::DbResult*	result = Configuration::GetConfiguration()->GetDatabase()->SelectChannelBanListLogin(id);
	for (unsigned int idx = 0; idx < result->size(); idx++)
		this->_banList.push_back((*result->at(idx))["idUser"]->GetValueInt());
	delete result;
}

AgoraAdmin::Channel::~Channel(void)
{
}

const unsigned int	AgoraAdmin::Channel::GetId(void) const
{
	return this->_id;
}

AgoraAdmin::IChannel*	AgoraAdmin::Channel::GetParent(void) const
{
	return this->_parent;
}

const unsigned int	AgoraAdmin::Channel::GetParentId(void) const
{
	return this->_idParent;
}

void				AgoraAdmin::Channel::SetParent(IChannel* parent)
{
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelIdParent(this->_id, parent->GetId());
	//changement dans le host
	if (this->_parent)
		this->_parent->RemoveChannelChild(this);
	this->_parent = parent;
	this->_parent->AddChannelChild(this);
}

void	AgoraAdmin::Channel::SetParentNODB(IChannel* parent)
{
	this->_parent = parent;
}

const bool	AgoraAdmin::Channel::HaveParent(void) const
{
	if (this->_parent)
		return true;
	return false;
}

const std::string&	AgoraAdmin::Channel::GetName(void) const
{
	return this->_name;
}

void				AgoraAdmin::Channel::SetName(const std::string& name)
{
	//changement dans la base
	Configuration::GetConfiguration()->GetDatabase()->UpdateChannelName(this->_id, name);
	this->_name = name;
}

const unsigned int	AgoraAdmin::Channel::GetMaxNameLength(void) const
{
	return this->_maxNameLenght;
}

void				AgoraAdmin::Channel::SetMaxNameLength(const unsigned int length, bool recurcive)
{
	if (recurcive)
	{
		std::list<IChannel*>::iterator	iteCurrent = this->_child.begin();
		std::list<IChannel*>::iterator	iteEnd = this->_child.end();
		while (iteCurrent != iteEnd)
		{
			(*iteCurrent)->SetMaxNameLength(length, true);
			++iteCurrent;
		}
	}
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelMaxNameLenght(this->_id, length);
	this->_maxNameLenght = length;
}

const std::string&	AgoraAdmin::Channel::GetPassword(void) const
{
	return this->_password;
}

void				AgoraAdmin::Channel::SetPassword(const std::string& password, bool recurcive)
{
	if (recurcive)
	{
		std::list<IChannel*>::iterator	iteCurrent = this->_child.begin();
		std::list<IChannel*>::iterator	iteEnd = this->_child.end();
		while (iteCurrent != iteEnd)
		{
			(*iteCurrent)->SetPassword(password, true);
			++iteCurrent;
		}
	}
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelPassword(this->_id, password);
	this->_password = password;
}

const unsigned int	AgoraAdmin::Channel::GetMaxPasswordLength(void) const
{
	return this->_maxPasswordLenght;
}

void				AgoraAdmin::Channel::SetMaxPasswordLength(const unsigned int length, bool recurcive)
{
	if (recurcive)
	{
		std::list<IChannel*>::iterator	iteCurrent = this->_child.begin();
		std::list<IChannel*>::iterator	iteEnd = this->_child.end();
		while (iteCurrent != iteEnd)
		{
			(*iteCurrent)->SetMaxPasswordLength(length, true);
			++iteCurrent;
		}
	}
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelMaxPasswordLenght(this->_id, length);
	this->_maxPasswordLenght = length;
}

const std::string&	AgoraAdmin::Channel::GetMotd(void) const
{
	return this->_motd;
}

void				AgoraAdmin::Channel::SetMotd(const std::string& motd, bool recurcive)
{
	if (recurcive)
	{
		std::list<IChannel*>::iterator	iteCurrent = this->_child.begin();
		std::list<IChannel*>::iterator	iteEnd = this->_child.end();
		while (iteCurrent != iteEnd)
		{
			(*iteCurrent)->SetMotd(motd, true);
			++iteCurrent;
		}
	}
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelMotd(this->_id, motd);
	this->_motd = motd;
}

const unsigned int	AgoraAdmin::Channel::GetMaxMotdLength(void) const
{
	return this->_maxMotdLenght;
}

void				AgoraAdmin::Channel::SetMaxMotdLength(const unsigned int length, bool recurcive)
{
	if (recurcive)
	{
		std::list<IChannel*>::iterator	iteCurrent = this->_child.begin();
		std::list<IChannel*>::iterator	iteEnd = this->_child.end();
		while (iteCurrent != iteEnd)
		{
			(*iteCurrent)->SetMaxMotdLength(length, true);
			++iteCurrent;
		}
	}
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelMaxMotdLenght(this->_id, length);
	this->_maxMotdLenght = length;
}

const std::string&	AgoraAdmin::Channel::GetDescription(void) const
{
	return this->_description;
}

void				AgoraAdmin::Channel::SetDescription(const std::string& description, bool recurcive)
{
	if (recurcive)
	{
		std::list<IChannel*>::iterator	iteCurrent = this->_child.begin();
		std::list<IChannel*>::iterator	iteEnd = this->_child.end();
		while (iteCurrent != iteEnd)
		{
			(*iteCurrent)->SetDescription(description, true);
			++iteCurrent;
		}
	}
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelDescription(this->_id, description);
	this->_description = description;
}

const unsigned int	AgoraAdmin::Channel::GetMaxDescriptionLength(void) const
{
	return this->_maxDescriptionLenght;
}

void				AgoraAdmin::Channel::SetMaxDescriptionLength(const unsigned int length, bool recurcive)
{
	if (recurcive)
	{
		std::list<IChannel*>::iterator	iteCurrent = this->_child.begin();
		std::list<IChannel*>::iterator	iteEnd = this->_child.end();
		while (iteCurrent != iteEnd)
		{
			(*iteCurrent)->SetMaxDescriptionLength(length, true);
			++iteCurrent;
		}
	}
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelMaxDesciptionLenght(this->_id, length);
	this->_maxDescriptionLenght = length;
}

const bool			AgoraAdmin::Channel::GetVisibility(void) const
{
	return this->_visible;
}

void				AgoraAdmin::Channel::SetVisibility(const bool visible, bool recurcive)
{
	if (recurcive)
	{
		std::list<IChannel*>::iterator	iteCurrent = this->_child.begin();
		std::list<IChannel*>::iterator	iteEnd = this->_child.end();
		while (iteCurrent != iteEnd)
		{
			(*iteCurrent)->SetVisibility(visible, true);
			++iteCurrent;
		}
	}
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelVisibility(this->_id, visible);
	this->_visible = visible;
}

const unsigned int	AgoraAdmin::Channel::GetMaxUser(void) const
{
	return this->_maxUser;
}

void				AgoraAdmin::Channel::SetMaxUser(const unsigned int limit, bool recurcive)
{
	if (recurcive)
	{
		std::list<IChannel*>::iterator	iteCurrent = this->_child.begin();
		std::list<IChannel*>::iterator	iteEnd = this->_child.end();
		while (iteCurrent != iteEnd)
		{
			(*iteCurrent)->SetMaxUser(limit, true);
			++iteCurrent;
		}
	}
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelMaxUser(this->_id, limit);
	this->_maxUser = limit;
}

const unsigned int	AgoraAdmin::Channel::GetMaxTalker(void) const
{
	return this->_maxTalker;
}

void				AgoraAdmin::Channel::SetMaxTalker(const unsigned int limit, bool recurcive)
{
	if (recurcive)
	{
		std::list<IChannel*>::iterator	iteCurrent = this->_child.begin();
		std::list<IChannel*>::iterator	iteEnd = this->_child.end();
		while (iteCurrent != iteEnd)
		{
			(*iteCurrent)->SetMaxTalker(limit, true);
			++iteCurrent;
		}
	}
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->UpdateChannelMaxTalker(this->_id, limit);
	this->_maxTalker = limit;
}

void				AgoraAdmin::Channel::DeleteChannel(void)
{
	//changement dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->DeleteChannel(this->_id);
	//pas utile ici on le doit le faire via le right manager qui sera appele via l'interpreter
	//AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->DeleteChannelRightChannel(this->_id);
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->DeleteChannelBanList(this->_id);
}

void				AgoraAdmin::Channel::AddChannelChild(IChannel* channel)
{
	this->_child.push_back(channel);
}

void				AgoraAdmin::Channel::RemoveChannelChild(IChannel* channel)
{
	this->_child.remove(channel);
}

std::list<AgoraAdmin::IChannel*>&	AgoraAdmin::Channel::GetChannelChild(void)
{
	return this->_child;
}

void				AgoraAdmin::Channel::AddUser(IUser* user)
{
	this->_user.push_back(user);
	user->SetCurrentChannelId(this->GetId());
}

void				AgoraAdmin::Channel::RemoveUser(IUser* user)
{
	this->_user.remove(user);
	user->SetCurrentChannelId(0);
}

std::list<AgoraAdmin::IUser*>&	AgoraAdmin::Channel::GetUser()
{
	return this->_user;
}

std::list<unsigned int>&	AgoraAdmin::Channel::GetBanList()
{
	return this->_banList;
}

void	AgoraAdmin::Channel::AddBanList(const unsigned int idUser)
{
	this->RemoveBanList(idUser);
	//ajout dans la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->InsertChannelBanListLogin(this->_id, idUser);
	this->_banList.push_back(idUser);
}

void	AgoraAdmin::Channel::RemoveBanList(const unsigned int idUser)
{
	//remove de la base
	AgoraAdmin::Configuration::GetConfiguration()->GetDatabase()->DeleteChannelBanListLogin(this->_id, idUser);
	this->_banList.remove(idUser);
}

bool	AgoraAdmin::Channel::UserIsBan(const unsigned int idUser)
{
	std::list<unsigned int>::iterator	iteCurrent = this->_banList.begin();
	std::list<unsigned int>::iterator	iteEnd = this->_banList.end();

	while (iteCurrent != iteEnd)
	{
		if ((*iteCurrent) == idUser)
			return true;
		++iteCurrent;
	}
	return false;
}

std::map<unsigned int, AgoraAdmin::IUser*>&	AgoraAdmin::Channel::GetMuteMap()
{
	return this->_muteList;
}

std::list<AgoraAdmin::IUser*>&					AgoraAdmin::Channel::GetMuteList()
{
	std::list<AgoraAdmin::IUser*>*	lst = new std::list<AgoraAdmin::IUser*>();
	//parcours de la map et push des users dans la list
	std::map<unsigned int, AgoraAdmin::IUser*>::iterator	iteCurrent = this->_muteList.begin();
	std::map<unsigned int, AgoraAdmin::IUser*>::iterator	iteEnd = this->_muteList.end();
	while (iteCurrent != iteEnd)
	{
		lst->push_back((*iteCurrent).second);
		++iteCurrent;
	}
	return *lst;
}

void								AgoraAdmin::Channel::AddMuteUser(IUser* user)
{
	if (this->_muteList.count(user->GetId()) == 0)
		this->_muteList[user->GetId()] = user;
}

void								AgoraAdmin::Channel::RemoveMuteUser(IUser* user)
{
	this->_muteList.erase(user->GetId());
}

bool								AgoraAdmin::Channel::UserIsMute(IUser* user)
{
	if (this->_muteList.count(user->GetId()) != 0)
		return true;
	return false;
}
